package com.wzapp.sitposture.authentication.endpoint;

import com.wzapp.sitposture.common.error.ErrorMessage;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.oauth2.common.exceptions.InvalidGrantException;
import org.springframework.security.oauth2.common.exceptions.InvalidTokenException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 功能: <br/>
 *
 * @author ql
 * @version 0.4
 * @create 2018-06-30 17:53
 **/
public class CustomizedAuthenticationEntryPoint implements org.springframework.security.web.AuthenticationEntryPoint {

    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
        ErrorMessage errorMessage = getErrorMessage(authException);

        response.setContentType("application/json");
        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        try {
            ObjectMapper mapper = new ObjectMapper();
            mapper.writeValue(response.getOutputStream(), errorMessage);
        } catch (Exception e) {
            throw new ServletException("parse oatuhexception error",e);
        }
    }

    /**
     * 功能: 自定义返回异常信息<br/>
     *
     * @param authException
     * @return ErrorMessage
     * @author ql
     * @create 2018-07-02 18:07
     **/
    private ErrorMessage getErrorMessage(Throwable authException) {
        Throwable throwable = obtainThrowable(authException);
        ErrorMessage errorMessage = new ErrorMessage();
        errorMessage.setCode(401);
        String message = throwable.getMessage();
        errorMessage.setMessage(message);
        if (throwable instanceof InvalidTokenException) {
            errorMessage.setCode(204010);
            errorMessage.setMessage("access_token过期，请刷新token！");
            if (null!=message&&message.contains("Invalid refresh token (expired):")){
                errorMessage.setCode(204011);
                errorMessage.setMessage("登录已失效，请重新登录！");
            }
        }
        if (throwable instanceof InvalidGrantException) {
            errorMessage.setCode(204011);
            errorMessage.setMessage("登录已失效，请重新登录！");
        }
        if (throwable instanceof BadCredentialsException) {
            errorMessage.setCode(102011);
            errorMessage.setMessage("请您先登录！");
        }
        if (throwable instanceof InsufficientAuthenticationException) {
            errorMessage.setCode(204009);
            errorMessage.setMessage("请您提供access_token");
        }
        return errorMessage;
    }

    private Throwable obtainThrowable(Throwable ex) {

        Throwable throwable = ex;
        while (throwable != null) {
            if (null == throwable.getCause()) {
                break;
            }
            throwable = throwable.getCause();
        }
        return throwable;
    }
}
